package com.weijianhuawen.wjblog.web.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.weijianhuawen.wjblog.common.domain.dos.CommentDo;
import com.weijianhuawen.wjblog.common.domain.mapper.BlogSettingsMapper;
import com.weijianhuawen.wjblog.common.domain.mapper.CommentMapper;
import com.weijianhuawen.wjblog.common.enums.CommentStatusEnum;
import com.weijianhuawen.wjblog.common.enums.ResponseCodeEnum;
import com.weijianhuawen.wjblog.common.exception.BizException;
import com.weijianhuawen.wjblog.common.utils.Response;
import com.weijianhuawen.wjblog.web.convert.CommentConvert;
import com.weijianhuawen.wjblog.web.mode.vo.comment.*;
import com.weijianhuawen.wjblog.web.service.CommentService;
import com.weijianhuawen.wjblog.web.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;


import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @version: java version 8
 * @Author: weijianhuawen
 * @description:
 * @date: 2024-12-08 15:49
 */
@Slf4j
@Service
public class CommentServiceImpl implements CommentService {
    @Resource
    private RestTemplate restTemplate;
    @Resource
    private BlogSettingsMapper blogSettingsMapper;
    @Resource
    private CommentMapper commentMapper;

    /**
     * 根据qq号码获取基本信息
     * @param vo 请求体
     * @return 基本信息
     */
    @Override
    public Response findQQUserInfo(FindQQUserInfoReqVo vo) {
        // 获取qq号码
        String qqId = vo.getQId();
        // 校验qq号码
        if (!StringUtil.isPureNumber(qqId)) {
            // qq号不是纯数字
            log.warn("请求参数QQ号码不是纯数字！");
            throw new BizException(ResponseCodeEnum.QQ_ID_ILLEGAL);
        }
        // 请求第三方接口
        String url = String.format("https://api.qjqq.cn/api/qqinfo?qq=%s", qqId);
        String result = restTemplate.getForObject(url, String.class);

        log.info("通过qq号码：" + qqId + "获取信息成功！");

        // 解析响应参数
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            Map<String, Object> map = objectMapper.readValue(result, Map.class);
            if (Objects.equals(map.get("code"), HttpStatus.OK.value())) {
                // 请求成功
                // 获取用户头像，昵称，邮箱
                FindQQUserInfoRspVo findQQUserInfoRspVo = FindQQUserInfoRspVo.builder()
                        .avatar(String.valueOf(map.get("imgurl")))
                        .nickName(String.valueOf(map.get("name")))
                        .email(String.valueOf(map.get("mail")))
                        .build();
                return Response.success(findQQUserInfoRspVo);
            } else return Response.fail();
        } catch (JsonProcessingException e) {
            throw new BizException(ResponseCodeEnum.JSON_TRANSLATION_ERROR);
        } catch (Exception e) {
            throw new BizException(ResponseCodeEnum.GET_QQ_INFO_FAIL);
        }
    }

    @Override
    public Response findCommentList(FindCommentListReqVo vo) {
        // 获取评论所在的路由地址
        String routerUrl = vo.getRouterUrl();

        // 查询在该路由下的所有状态为正常的评论
        List<CommentDo> commentDos = commentMapper.selectByRouterUrlAndStatus(routerUrl, CommentStatusEnum.NORMAL.getCode());
        // 获取总评论数
        Integer total = commentDos.size();

        // 结构化评论区
        List<FindCommentItemRspVo> vos = commentsStructuring(commentDos);

        // 响应请求
        return Response.success(FindCommentListRspVo.builder()
                .comments(vos)
                .total(total)
                .build());
    }

    private List<FindCommentItemRspVo> commentsStructuring(List<CommentDo> commentDos) {
        List<FindCommentItemRspVo> result = Lists.newArrayList();

        // 提取一级评论
        result = commentDos.stream()
                .filter(commentDo -> Objects.isNull(commentDo.getParentCommentId()))
                .map(commentDo -> CommentConvert.INSTANCE.convertCommentDo2ItemVo(commentDo))
                .collect(Collectors.toList());

        // 遍历所有一级评论，提取子评论
        result.forEach(vo -> {
            // 获取父评论id
            Long parentId = Long.valueOf(vo.getId());
            // 筛选出所有父评论id为parentId的评论
            List<FindCommentItemRspVo> children = commentDos.stream()
                    .filter(commentDo -> Objects.equals(parentId, commentDo.getParentCommentId()))
                    .sorted(Comparator.comparing(CommentDo::getCreateTime))
                    .map(commentDo -> {
                        FindCommentItemRspVo findCommentItemRspVo = CommentConvert.INSTANCE.convertCommentDo2ItemVo(commentDo);
                        Long replyCommentId = commentDo.getReplyCommentId();
                        // 如果子评论的回复id不是父评论id，则标记为子评论回复，前端需做@处理
                        if (!Objects.equals(parentId, replyCommentId)) {
                            // 获取被评论人评论信息
                            Optional<CommentDo> optionalCommentDo = commentDos.stream()
                                    .filter(replyCommentDo -> Objects.equals(replyCommentDo.getId(), replyCommentId))
                                            .findFirst();

                            // 设置被@用户的相关信息
                            optionalCommentDo.ifPresent(aDo -> {
                                findCommentItemRspVo.setReplyNickname(aDo.getNickname());
                                findCommentItemRspVo.setReplyUserId(String.valueOf(aDo.getUserId()));
                            });
                        }
                        return findCommentItemRspVo;
                    })
                    .collect(Collectors.toList());

            // 设置子评论
            vo.setChildComments(children);
        });

        return result;
    }
}
